#include "TIMER.h"

TIMER_T* TIMER_t;



//************************************
// Method:    	CALCU_SAMA						//< SAMA运算函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	bool							//< 成功：true；失败：false
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	float dt						//< 运算周期
// Parameter: 	bool * DI						//< 数字量输入值数组指针
// Parameter: 	bool * DO						//< 数字量输出值数组指针
// Parameter: 	bool * AI						//< 模拟量输入值数组指针
// Parameter: 	bool * AO						//< 模拟量输出值数组指针
//************************************
bool CALCU_SAMA(TIMER)(Model_Base_t* arg, float dt, bool* DI, bool* DO, float* AI, float* AO)
{
	/****************变量定义区开始**************/
	/*<<<<<定义输入变量>>>>>*/
	float Time;					//< 定时时间
	bool Sd;					//< 置位信号
	bool Rd;					//< 复位信号
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<定义输出变量>>>>>*/
	/*float LeastTime = 0;*/			//< 剩余时间					//< duan0902 将其设计成中间变量，避免强制、保持对其正常运算造成影响	
	bool Out_Signal = false;		//< 定时器输出信号
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<定义参数变量>>>>>*/
	TIMER_WORK_t type;			//< 定时器工作方式
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<定义中间变量>>>>>*/
	bool* Sd_Last;			//< 上一时刻置位信号
	bool* Rd_Last;			//< 上一时刻复位信号
	bool* Count_Time_Flg;	//< 计时标志位，该位置1，开始计时
	bool* TIMER_LAG_RD_Flag;
	bool* TIMER_LAG_SD_HOLD_Flag;
	float* LeastTime;		//< duan0902
	bool* LastDO;			//< duan0902
	/*<<<<<<<<<<<<<<<<<<<<<<*/
	/****************变量定义区结束**************/

	NAME(TIMER)* Obj = (NAME(TIMER)*)arg;

	/****************变量赋值**************/
	/*<<<<<输入变量赋值>>>>>*/
	Time = AI[0];
	Sd = DI[0];
	Rd = DI[1];
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<参数变量赋值>>>>>*/
	type = Obj->Par.type;
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<中间变量赋值（由于中间变量属于静态变量，其数值要随运算而更新，
	因此此处建议将中间变量的地址赋值给相应变量，省去了运算完成后再次赋值
	给中间变量的过程）>>>>>*/
	Sd_Last = &(Obj->Sta.Sd_Last);
	Rd_Last = &(Obj->Sta.Rd_Last);
	Count_Time_Flg = &(Obj->Sta.Count_Time_Flg);
	TIMER_LAG_RD_Flag = &(Obj->Sta.TIMER_LAG_RD_Flag);
	TIMER_LAG_SD_HOLD_Flag = &(Obj->Sta.TIMER_LAG_SD_HOLD_Flag);
	LeastTime = &(Obj->Sta.LeastTime);
	LastDO = &(Obj->Sta.LastDO);
	/*<<<<<<<<<<<<<<<<<<<<<<*/
	/**************变量赋值结束************/

	/********************************************/
	/**************算法功能实现开始**************/
	/********************************************/
	switch (type) {
	case TIMER_BASE:
		//< 该定时模式下，输出为高电平仅会持续一个运算周期，因此检测到上一时刻输出为高电平，则令当前输出清零
		/*if (Obj->Base.Out.DO[0] == true)
			Out_Signal = false;*/
		if (LastDO[0] == true)
			Out_Signal = false;
		if (Count_Time_Flg[0] == true)						//< duan0901 计时开始
		{
			/*LeastTime = Obj->Base.Out.AO[0] - dt;*/
			LeastTime[0] -= dt;
			if (LeastTime[0] < 0) { LeastTime[0] = 0; }
			if (LeastTime[0] == 0) 
			{ 
				Out_Signal = true; 
				Count_Time_Flg[0] = false; 
			}
		}
		if (Rd_Last[0] == false && Rd == true)				//< 复位信号上升沿
		{
			Count_Time_Flg[0] = false;
			LeastTime[0] = 0;
			Out_Signal = false;
		}
		else if (Sd_Last[0] == false && Sd == true)			//< 置位信号上升沿
		{
			Count_Time_Flg[0] = true;
			LeastTime[0] = Time;
		}
		break;
	case TIMER_SINGLE_PULSE:
		if (Count_Time_Flg[0] == true)
		{
			/*LeastTime = Obj->Base.Out.AO[0] + dt;*/
			LeastTime[0] += dt;
			if (LeastTime[0] < Time)
				Out_Signal = true;
			else
			{
				Count_Time_Flg[0] = false;
				LeastTime[0] = 0;
				Out_Signal = false;
			}
		}
		if (Rd_Last[0] == false && Rd == true)				//< 复位信号上升沿
		{
			Count_Time_Flg[0] = false;
			LeastTime[0] = 0;
			Out_Signal = false;
		}
		else if (Sd_Last[0] == false && Sd == true)			//< 置位信号上升沿
		{
			Count_Time_Flg[0] = true;
			LeastTime[0] = 0;
			Out_Signal = true;
		}
		break;
	case TIMER_LAG_SD:
		if (Count_Time_Flg[0] == true)
		{
			/*LeastTime = Obj->Base.Out.AO[0] - dt;*/
			LeastTime[0] -= dt;
			if (LeastTime[0] > 0)
				Out_Signal = false;
			else
			{
				Out_Signal = true;
				LeastTime[0] = 0;
			}
		}
		if (Rd_Last[0] == false && Rd == true)				//< 复位信号上升沿
		{
			Count_Time_Flg[0] = false;
			LeastTime[0] = 0;
			Out_Signal = false;
		}
		else if (Sd == false)								//< 置位信号不满足
		{
			Count_Time_Flg[0] = false;
			LeastTime[0] = 0;
			Out_Signal = false;
		}
		else if (Sd_Last[0] == false && Sd == true)			//< 置位信号上升沿
		{
			Count_Time_Flg[0] = true;
			LeastTime[0] = Time;
			Out_Signal = false;
		}
		break;
	case TIMER_LAG_RD:
		if (Count_Time_Flg[0] == true)
		{
			/*LeastTime = Obj->Base.Out.AO[0] - dt;*/
			LeastTime[0] -= dt;
			if (LeastTime[0] > 0)
				Out_Signal = true;
			else
			{
				Out_Signal = false;
				LeastTime[0] = 0;
			}
		}
		if (Rd_Last[0] == false && Rd == true)				//< 复位信号上升沿
		{
			Count_Time_Flg[0] = false;
			LeastTime[0] = 0;
			Out_Signal = false;
			TIMER_LAG_RD_Flag[0] = false;
		}
		else if (Sd_Last[0] == true && Sd == false && TIMER_LAG_RD_Flag[0] == true)			//< 置位信号下降沿
		{
			Count_Time_Flg[0] = true;
			LeastTime[0] = Time;
			Out_Signal = true;
		}
		else if (Sd_Last[0] == false && Sd == true)			//< 置位信号上升沿
		{
			TIMER_LAG_RD_Flag[0] = true;
			Count_Time_Flg[0] = false;
			LeastTime[0] = 0;
			Out_Signal = true;
		}
			
		else if (Sd == true && TIMER_LAG_RD_Flag[0] == true)//< 置位信号满足
		{
			LeastTime[0] = 0;
			Out_Signal = true;
		}
		break;
	case TIMER_LAG_SD_HOLD:
		if (Count_Time_Flg[0] == true)
		{
			/*LeastTime = Obj->Base.Out.AO[0] - dt;*/
			LeastTime[0] -= dt;
			if (LeastTime[0] > 0)
				Out_Signal = false;
			else
			{
				Out_Signal = true;
				LeastTime[0] = 0;
			}
		}
		//< ShiKe20200924下一行为原条件：
		//< if (Rd_Last[0] == false && Rd == true)	////< 复位信号上升沿
		if (Rd == true)			//< ShiKe20200924 修改过的条件：复位信号为1		
		{
			TIMER_LAG_SD_HOLD_Flag[0] = false;
			Count_Time_Flg[0] = false;
			LeastTime[0] = 0;
			Out_Signal = false;
		}
		else if (Sd_Last[0] == false && Sd == true && TIMER_LAG_SD_HOLD_Flag[0] == false)			//< 置位信号上升沿
		{
			Count_Time_Flg[0] = true;
			LeastTime[0] = Time;
			Out_Signal = false;
		}
		else if (Sd_Last[0] == true && Sd == false)			//< 置位信号下降沿
			TIMER_LAG_SD_HOLD_Flag[0] = true;
		break;
	}
	Sd_Last[0] = Sd;
	Rd_Last[0] = Rd;
	LastDO[0] = Out_Signal;
	/********************************************/
	/**************算法功能实现结束**************/
	/********************************************/	

	/****************运算结果输出**************/
	AO[0] = LeastTime[0];
	DO[0] = Out_Signal;
	//< printf("the pluse is %d\r\n", Out_Signal);
	/**************运算结果输出完毕************/
	return true;
}



//************************************
// Method:    	BCPARA							//< 广播SAMA参数变量函数（无参数需要广播的模块直接将BCPara函数设置为NULL即可）
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int								//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	void ** Data					//< 广播SAMA参数的数据包的指针
//************************************
int BC_PARA(TIMER)(Model_Base_t* arg, void** Data)
{
	NAME(TIMER)* Obj = (NAME(TIMER)*)arg;
	BC_PARA_PUBLIC(Obj);
	return 0;
}



//************************************
// Method:    	BAK_STA							//< 备份SAMA运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int								//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 指定模块类型链表的指针
// Parameter: 	void ** Data					//< 存放数据包当前指针位置的地址
//************************************
int BAK_STA(TIMER)(Model_Base_t* arg, void** Data)
{
	NAME(TIMER)* Obj = (NAME(TIMER)*)arg;
	BAK_STA_PRIVATE(Obj);
	return 0;
}



//************************************
// Method:    	ANA_STA							//< 解析备份的SAMA运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int								//< 成功：返回解析字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	void ** Data					//< 存放数据包当前指针位置的地址
//************************************
int ANA_STA(TIMER)(Model_Base_t* arg, void** Data)
{
	NAME(TIMER)* Obj = (NAME(TIMER)*)arg;
	ANA_STA_PRIVATE(Obj);
	return 0;
}



//************************************
// Method:    	CHANGE_PAR				//< 在线修改模块参数函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int						//< 读取字节长度计数值
// Parameter: 	Model_Base_t* arg		//< 指定模块类型链表的指针
// Parameter: 	void** Data				//< 存放数据包当前指针位置的地址
//************************************
int CHANGE_PAR(TIMER)(Model_Base_t* arg, void** Data)
{
	int _iLen = 0;
	MEMREAD(((NAME(TIMER)*)arg)->Par, Data[0]);
	return _iLen;
}



//************************************
// Method:    	INIT_STAPAR						//< 初始化模块运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Parameter: 	Model_Base_t* arg				//< 模块参数结构体指针
//************************************
void INIT_STAPAR(TIMER)(Model_Base_t* arg)
{
	NAME(TIMER)* name = (NAME(TIMER)*)arg;
	/****************初始化中间变量结构体**************/
	memset(&(name->Sta), 0, sizeof(name->Sta));
	/**************初始化中间变量结构体结束************/

	/****************对中间变量结构体的相关参数进行赋值**************/

	/**************对中间变量结构体的相关参数进行赋值结束************/
}
